import libtcodpy as L#libtcod library
import sys
import cPickle
import random as RNG#rng instead of random
import math
import traceback
import os
RNG.seed()#seed the rng for further use
from Settings import *#so everything has access to settings
#file path
FILE_PATH = "test.txt"
#font
font = "Fonts/BrogueFont5.png"
#screen width and height
SCREEN_WIDTH = 30
SCREEN_HEIGHT = 20
#for the viewing area
VIEWING_AREA_WIDTH = 15
VIEWING_AREA_HEIGHT = 15
VIEWING_AREA_SCROLLX = 0
VIEWING_AREA_SCROLLY = 0
#messages
MESSAGE_NUMBER = 5#number of messages
MESSAGE_MAX_WIDTH = 30#maximum message width
MAX_MAP_WIDTH = 16*16
MAX_MAP_HEIGHT = 16*16
#FOV
FOV_ALGO = L.FOV_SHADOW
FOV_LIGHT_WALLS = True
TORCH_RADIUS = 6
#FPS
GAME_FPS = 24#will be jerky if game FPS is set too low
#colors
color_dark_wall = L.Color(0,0,100)
color_light_wall = L.Color(130, 110, 50)
color_dark_ground = L.Color(50,50,150)
color_light_ground = L.Color(200, 180, 50)

#keys for refrencing layers
A_PLAYER = "Player"
A_MAP = "Map"

#layers
L_CRE = "Creatures"
L_INV = "Items"
L_RAN = "Ranged"
L_TRA = "Traps"

#screens
S_NOR = "Normal screen"
S_INV = "Inventory screen"
S_MAP = "Map travel screen"
S_PIC = "Pickup screen"#???
S_HEL = "Help screen"

#factions
F_PLA = 'p'#player
F_MON = 'm'#monster

#slots for the inventory
EQ_NONE = "No Slot"
EQ_ARMOR = "Armor Slot"
EQ_WEAPON = "Weapon Slot"

#handling the game
global g
g = None
def Game():
	return g

def setGame(game):
	global g
	g = game
#handling the messages
global messages
messages = [["",L.white] for i in range(MESSAGE_NUMBER)]

#add a message to the end and remove one from the beginning
def addMessage(message,color=L.white):
	global messages
	while (len(message) > MESSAGE_MAX_WIDTH):#trim the length
		messages.append([message[0:MESSAGE_MAX_WIDTH-1],color])
		messages.pop(0)
		message = message[MESSAGE_MAX_WIDTH:]
	messages.append([message,color])#append the message
	messages.pop(0)
#display the messages
def displayMessages():
	for i in range(MESSAGE_NUMBER):
		L.console_set_foreground_color(None,messages[i][1])
		L.console_print_left(None,0,15+i,L.BKGND_NONE,messages[i][0])
def greyMessages():
	for i in range(MESSAGE_NUMBER):
		messages[i][1] = L.grey
#display the stats
def displayStatus():
	player = Game()[A_PLAYER]
	healthbarparts = int((float(player.hp)/player.max_hp)*15)#calculate the size of the healthbar
	healthbarend = (float(player.hp)/player.max_hp)*15-healthbarparts#the magnitude of the end
	L.console_set_foreground_color(None,L.white)
	L.console_print_center(None,22,0,L.BKGND_NONE,"HP:("+str(player.max_hp)+")")
	if (player.hp <= player.max_hp*0.2):#the hp text colors#low health
		color = L.red
	elif (player.hp <= player.max_hp*0.5):#warning, half health
		color = L.yellow
	else:
		color = L.green
	#L.console_print_left(None,18,0,L.BKGND_NONE,str(player.hp))
	for i in range(healthbarparts):
		L.console_set_back(None,15+i,0,color,L.BKGND_SET)
	if (healthbarend > 0):#do the end of the health bar
		L.console_set_back(None,15+healthbarparts,0,color*healthbarend,L.BKGND_SET)
	L.console_set_foreground_color(None,L.white)
	L.console_print_center(None,22,1,L.BKGND_NONE,"MP:(1)")
	for i in range(15):
		L.console_set_back(None,15+i,1,L.blue,L.BKGND_SET)
#display functions
def displayHelp():
	L.console_set_foreground_color(None,L.white)
	#L.console_set_background_color(None,L.blue)
	#lines for the help menu
	help_lines = ["Press q to exit a menu.",
				"y k u  or keypad 7 8 9",
				" \|/              \|/ ",
				"h-.-l            4-5-6 - move",
				" /|\              /|\ ",
				"b j n            1 2 3",
				"",
				"Press d to drop an item.",
				"Press a to use an item.",
				"Press , to pickup an item.",
				"Press w to wield an item.",
				"Bump into monsters to attack."
				]
	for i in range(len(help_lines)):
		L.console_print_left(0,0,i,L.BKGND_NONE,help_lines[i])

#initialize the ranged targeting interface
ranged_console = L.console_new(VIEWING_AREA_WIDTH,VIEWING_AREA_HEIGHT)
L.console_set_key_color(ranged_console,L.black)
wieldingranged = True
def displayRanged():#display the ranged console if the player is wielding a ranged weapon
	if (Game()[A_PLAYER].targetranged):
		L.console_blit(ranged_console,0,0,VIEWING_AREA_WIDTH,VIEWING_AREA_HEIGHT,None,0,0,0.0,0.3)
	else:
		pass
def displayNormal():
	displayMessages()#display messages and status
	displayStatus()
	Game()[A_MAP].showMap()#show the map
	displayRanged()#display targeting
def displayMap():
	Game()[A_MAP].showMap(width=SCREEN_WIDTH,height=SCREEN_HEIGHT)
def displayInventory():#display inventory
	L.console_set_foreground_color(None,L.white)
	if (Game()[A_PLAYER].displayselection == 'd'):
		L.console_print_left(0,0,0,L.BKGND_NONE,"Drop which item?")
	elif (Game()[A_PLAYER].displayselection == 'a'):
		L.console_print_left(0,0,0,L.BKGND_NONE,"Use which item?")
	elif (Game()[A_PLAYER].displayselection == 'e'):
		L.console_print_left(0,0,0,L.BKGND_NONE,"Equip which item?")
	else:
		L.console_print_left(0,0,0,L.BKGND_NONE,"Inventory")
	inv = Game()[A_PLAYER].inventory
	i = 1#line number
	#XXX: modify this to display inventory properly
	for key in inv.order:#print each item's name and key, to the limit of the screen space
		if (inv.items[key] != None):#key
			L.console_print_left(0,0,i,L.BKGND_NONE,str(key)+") ")
			L.console_print_left(0,3,i,L.BKGND_NONE,inv.inventoryName(key)[:SCREEN_WIDTH-3])
			i += 1#increment line number
#display selector
#controls what screens lead to what functions
displaySelector = {S_NOR:displayNormal,S_INV:displayInventory,S_HEL:displayHelp,S_MAP:displayMap}

def updateDisplay():#update the display
	L.console_clear(0)#clear the console
	displaySelector[Game()[A_PLAYER].displaytype]()#display the appropriate screen
	L.console_flush()
#wall sliding / movement stuff
def turnLeft(xmov, ymov):#left, relative move 1 square away
	if (xmov == -1):
		if (ymov == 1):
			return 0,1
		return -1,ymov+1
	if (xmov == 1):
		if (ymov == -1):
			return 0, -1
		return 1, ymov-1
	if (xmov == 0):
		return ymov, ymov
def turnRight(xmov, ymov):#right, relative move 1 square away
	if (xmov == -1):
		if (ymov == -1):
			return 0,-1
		return -1,ymov-1
	if (xmov == 1):
		if (ymov == 1):
			return 0, 1
		return 1, ymov+1
	if (xmov == 0):
		return -ymov, ymov

		